﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web;
using System.Web.Http;
using Cofe.Core;
using Cofe.Core.Filter;
using Cofe.Core.Implements;
using Cofe.Core.Property;
using Cofe.Core.Validater;
using Cofe.Data;

namespace Cofe.Web.Utils
{
    public static class ControllerUtils
    {
        public static ParameterDic getParamDicFromQueryString(object property)
        {
            //Debug.WriteLine(System.Web.HttpContext.Current.Request);
            if (DecoratorExtension.IsWebAction(property))
            {
                var aa = CofeServices.PropertyDictionary.AttributeHelper.FindAttribute<ActionAttribute>(property);
                return ParameterDic.FromNameValueCollection(System.Web.HttpContext.Current.Request.QueryString, aa.Parameters);
            }
            else
            {
                var wra = CofeServices.PropertyDictionary.AttributeHelper.FindAttribute<WebResourceAttribute>(property);
                return ParameterDic.FromNameValueCollection(System.Web.HttpContext.Current.Request.QueryString, wra.Parameters);
            }
        }

        public static Guid findEntryId(string path)
        {
            if (String.IsNullOrEmpty(path))
                return CofeConstants.RootGuid; //RootEntry
            else
                using (var repository = CofeDBServices.RepositoryFactory.CreateRepository())
                {
                    var dbEntry = repository.FindDbEntry(FilterCollections.FromParseName(path)).FirstOrDefault();
                    if (dbEntry == null)
                        return Guid.Empty;
                    return dbEntry.Id;
                }
        }


        public static object findProperty(IPropertyHost ph, string rel)
        {
            foreach (var l in UrlUtils.CreateLinks(ph))
                if (l.RelationTypeStr.Equals(rel, StringComparison.CurrentCultureIgnoreCase))
                {
                    return l.Property;
                }
            return null;
        }

        public static Uri findRedirect(IPropertyHost ph, string rel)
        {
            foreach (var l in UrlUtils.CreateLinks(ph))
                if (l.RelationTypeStr.Equals(rel, StringComparison.CurrentCultureIgnoreCase))
                {
                    return l.Uri;
                }
            return null;
        }

        public static HttpResponseMessage handleRedirect(ICofeSystemInfo entry, string rel)
        {
            var newUrl = findRedirect(entry.Properties, rel);
            if (newUrl != null)
            {
                newUrl = new Uri(newUrl.AbsoluteUri + HttpContext.Current.Request.QueryString
                    .ToQueryString(key => !key.Equals("rel", StringComparison.InvariantCultureIgnoreCase)));

                var response = new HttpResponseMessage(HttpStatusCode.Redirect);
                response.Headers.Location = newUrl;
                return response;
            }
            else return new HttpResponseMessage(HttpStatusCode.BadRequest);
        }

        public static DateTime? getLastModifiedTime(CofeSystemInfo entry, bool isListing)
        {
            DateTime? lastModifiedUtc = null;
            if (isListing && entry.Properties.Behaviors.IsPropertySupported(CacheProperties.LastListTimeUtc))
                lastModifiedUtc = entry.Properties.Behaviors.GetProperty<DateTime>(CacheProperties.LastListTimeUtc);
            else
                if (entry.Properties.Behaviors.IsPropertySupported(CacheProperties.LastCachedTimeUtc))
                    lastModifiedUtc = entry.Properties.Behaviors.GetProperty<DateTime>(CacheProperties.LastCachedTimeUtc);

            return lastModifiedUtc;
        }



        public static ResponseFormatterInfo createResponseFormatterInfo(WebResourceAttribute webResourceAttrib, DateTime? lastModifiedUtc)
        {
            var retVal = new ResponseFormatterInfo()
            {
                StatusCode = HttpStatusCode.OK,
                ResourceAttribute = webResourceAttrib
            };

            switch (webResourceAttrib.CacheMethod)
            {
                case WebCacheMethod.LastModified:
                    retVal.LastModified = lastModifiedUtc;
                    break;
                case WebCacheMethod.MaxAge:
                    retVal.MaxAge = TimeSpan.FromHours(0.5);
                    break;
            }

            return retVal;
        }
    }
}